//好友申请处理业务：
//获取好友申请记录
//验证是否有处理，不能重复处理
//修改申请结果，如果是通过，则建立两条好友关系记录，要用到【事务】

package logic

import (
	"context"
	"gitee.com/zxh/easy-chat/apps/social/socialmodels"
	"gitee.com/zxh/easy-chat/pkg/constants"
	"gitee.com/zxh/easy-chat/pkg/xerr"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/stores/sqlx"

	"gitee.com/zxh/easy-chat/apps/social/rpc/internal/svc"
	"gitee.com/zxh/easy-chat/apps/social/rpc/social"

	"github.com/zeromicro/go-zero/core/logx"
)

var (
	ErrFriendReqBeforePassed  = xerr.NewMsg("好友申请已经通过")
	ErrFriendReqBeforeRefused = xerr.NewMsg("好友申请已经被拒绝")
)

type FriendPutInHandleLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewFriendPutInHandleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FriendPutInHandleLogic {
	return &FriendPutInHandleLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *FriendPutInHandleLogic) FriendPutInHandle(in *social.FriendPutInHandleReq) (*social.FriendPutInHandleResp, error) {
	// 获取好友申请记录,如果没有查到申请记录，也当作错误来处理
	friendReq, err := l.svcCtx.FriendRequestsModel.FindOne(l.ctx, uint64(in.FriendReqId))
	if err != nil {
		return nil, errors.Wrapf(xerr.NewDBErr(), "IN FRIENDPUTINHANDLELOGIC find friendRequest by friendRedId err %v req %v", err, in.FriendReqId)
	}

	//验证是否有处理
	switch constants.HandlerResult(friendReq.HandleResult.Int64) {
	case constants.PassHandleResult:
		return nil, errors.WithStack(ErrFriendReqBeforePassed)
	case constants.RefuseHandleResult:
		return nil, errors.WithStack(ErrFriendReqBeforeRefused)
	}

	//更新处理结果
	friendReq.HandleResult.Int64 = int64(in.HandleResult)

	//修改申请结果，通过则建立两条好友关系记录 --》 事务 --》 先在好友申请模型中添加对事务的支持
	err = l.svcCtx.FriendRequestsModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		if err := l.svcCtx.FriendRequestsModel.Update(l.ctx, session, friendReq); err != nil {
			return errors.Wrapf(xerr.NewDBErr(), "IN FRIENDPUTINHANDLELOGIC update friend request err %v req %v", err, friendReq)
		}

		//若处理方式不为通过，则返回空
		if constants.HandlerResult(in.HandleResult) != constants.PassHandleResult {
			return nil
		}

		//记录好友关系,冗余存储AB、BA
		friends := []*socialmodels.Friends{
			{
				UserId:    friendReq.UserId,
				FriendUid: friendReq.ReqUid,
			}, {
				UserId:    friendReq.ReqUid,
				FriendUid: friendReq.UserId,
			},
		}

		//新增
		_, err = l.svcCtx.FriendsModel.Inserts(l.ctx, session, friends...)
		if err != nil {
			return errors.Wrapf(xerr.NewDBErr(), "IN FRIENDPUTINHANDLELOGIC insert friends err %v req %v", err, friends)
		}

		return nil
	})

	return &social.FriendPutInHandleResp{}, nil
}
